<?php

namespace common\model\sell66;

use common\db\Sell66;
use think\Exception;
use think\Log;

class OutTrade extends Sell66
{
	protected $table = 'out_trade';

	protected $pk = 'out_trade_id';

	public static $tradeStatusMap = [
		'time-out'	=> -100, // 超时
		'error-7'	=> -7, // 发送错误报价
		'error-6'	=> -6, // steam服务器不稳定
		'error-5'	=> -5, // 发送报价过多
		'error-4'	=> -4, // 无法交易，隐私或限制
		'error-3'	=> -3, // 交易链接失效，库存超限，限制
		'error-2'	=> -2, // 物品已取回
		'reading'	=> -1, // 准备
		'creating'	=> 9, // 已发起报价
		'waiting'	=> 2, // 已确认报价
		'success'	=> 3, // 报价成功
		'cancel'	=> 6, // 取消报价
		'deny'	=> 7, // 拒绝报价
	];

	public function outTradeDetail()
	{
		return $this->hasMany(OutTradeDetail::getClassName (), 'out_trade_id', 'out_trade_id');
	}

	public static function insertOutTrade($userId, $appId, $botId, array $invs)
	{
		$connection = (new self())->db();
		$connection->startTrans();

		try {
			$outTradeId = self::setOutTrade($userId, $botId, count($invs));
			if (!$outTradeId) {
				throw new Exception('insert out trade failed, user_id:'.$userId);
			}

			$res1 = OutTradeDetail::insertOutTradeDetail($outTradeId, $userId, $appId, $invs);
			if (!$res1) {
				throw new Exception('insert out trade details failed, out_trade_id:'.$outTradeId);
			}

			$connection->commit();
			return $outTradeId;
		} catch (\Exception $e) {
			echo $e->getMessage()."\r\n";
			$connection->rollback();
			return false;
		}
	}

	public static function setOutTrade($userId, $botId, $quantity)
	{
		$field = array(
			'user_id' => $userId,
			'bot_id' => $botId,
			'quantity' => $quantity,
			'tradeoffer_id' => '-1',
		);

		return static::insertGetId($field);
	}

	public static function getOutTradeByReadingTotals($userId)
	{
		$where = array(
			'user_id' => $userId,
			'tradeoffer_status' => OutTrade::$tradeStatusMap['reading'],
		);

		return static::where($where)->count();
	}

	public static function getOutTradeByReading()
	{
		$where = array(
			'tradeoffer_status' => OutTrade::$tradeStatusMap['reading'],
			'tradeoffer_out_id' => 0,
		);

		$result = static::where($where)->with('outTradeDetail')->select();

		return !empty($result) ? collection($result)->toArray() : array();
	}

	public static function updateOutTradeByTradeoffOutId($outTradeId, $tradeoffoutId)
	{
		$where = array(
			'out_trade_id' => $outTradeId,
		);

		$field = array(
			'tradeoffer_out_id' => $tradeoffoutId,
		);

		return static::where($where)->update($field);
	}

	public static function getOutTradeByCheckAll()
	{
		$between = array(
			self::$tradeStatusMap['reading'],
			self::$tradeStatusMap['creating'],
			self::$tradeStatusMap['waiting'],
		);

		$result = static::whereIn('tradeoffer_status', $between)->with('outTradeDetail')->select();

		return !empty($result) ? collection($result)->toArray() : array();
	}

	public static function updateOutTradeState($outTradeId, $tradeofferStatus)
	{
		$where = array(
			'out_trade_id' => $outTradeId,
		);

		$field = array(
			'tradeoffer_status' => $tradeofferStatus,
		);

		return static::where($where)->update($field);
	}

	public static function updateOutTradeByTradeId($outTradeId, $tradeofferId, $tradeofferStatus)
	{
		$where = array(
			'out_trade_id' => $outTradeId,
		);

		$field = array(
			'tradeoffer_id' => $tradeofferId,
			'tradeoffer_status' => $tradeofferStatus,
		);

		return static::where($where)->update($field);
	}

	public static function updateOutTrade($outTradeId, $tradeofferId, $tradeofferStatus, $details)
	{
		$connection = (new self())->db();
		$connection->startTrans();

		try {
			$res1 = self::updateOutTradeByTradeId($outTradeId, $tradeofferId, $tradeofferStatus);
			if (!$res1) {
				throw new Exception('update out trade failed, out_trade_id:'.$outTradeId);
			}

			$botInvIds = [];
			foreach ($details as $detail) {
				$botInvIds[] = $detail['bot_inv_id'];
			}

			if ($tradeofferStatus == OutTrade::$tradeStatusMap['success']) {
				$data = array(
					'out_trade_id' => $outTradeId,
					'bot_inv_ids' => $botInvIds,
				);

				$res2 = BotInv::updateTakeOutByUserId($botInvIds);
				if (!$res2) {
					throw new Exception('update bot inv take out failed, data:'.json_encode($data));
				}
			}

			if ($tradeofferStatus != OutTrade::$tradeStatusMap['success'] 
				&& $tradeofferStatus != OutTrade::$tradeStatusMap['waiting']
				&& $tradeofferStatus != OutTrade::$tradeStatusMap['creating']
				&& $tradeofferStatus != OutTrade::$tradeStatusMap['reading']) {
				// 异常状态，释放botinv物品
				$res3 = BotInv::updateDefaultByUserId($botInvIds);
				if (!$res3) {
					throw new Exception('update bot inv status failed, botinvids:'.json_encode($botInvIds));
				}
			}

			$connection->commit();
			return true;
		} catch (\Exception $e) {
			echo $e->getMessage()."\r\n";
			$connection->rollback();
			return false;
		}
	}

	public static function getOutTradeByTradeId($outTradeId)
	{
		$where = array(
			'out_trade_id' => $outTradeId,
		);

		$result = static::where($where)->find();

		return !empty($result) ? $result->toArray() : array();
	}

	public static function getOutTradeByOutNotice($userId, $outTradeId = NULL)
	{
		$where = array(
			'user_id' => $userId,
		);

		$whereIn = array(
			self::$tradeStatusMap['reading'],
			self::$tradeStatusMap['creating'],
			self::$tradeStatusMap['waiting'],
		);

		$query = static::where($where);
		if ($outTradeId) {
			$query->where('out_trade_id', '=', $outTradeId)->where('updated_at', '>=', date('Y-m-d H:i:s',(time() - 420)) );
		} else {
			$query->whereIn('tradeoffer_status', $whereIn);
		}

		$result = $query->select();

		return !empty($result) ? collection($result)->toArray() : array();
	}

	public static function updateTimeOutTrade($outTradeId, $tradeofferStatus, $details)
	{
		$connection = (new self())->db();
		$connection->startTrans();

		try {
			$res = self::updateOutTradeState($outTradeId, $tradeofferStatus);
			if (!$res) {
				throw new Exception('update out trade time out failed, out_trade_id:'.$outTradeId);
			}

			$botInvIds = [];
			foreach ($details as $detail) {
				$botInvIds[] = $detail['bot_inv_id'];
			}

			$res1 = BotInv::updateDefaultByUserId($botInvIds);
			if (!$res1) {
				throw new Exception('update bot inv time out failed, botinvids:'.json_encode($botInvIds));
			}

			$connection->commit();
			return true;
		} catch (\Exception $e) {
			echo $e->getMessage()."\r\n";
			$connection->rollback();
			return false;
		}
	}
}